﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Common.Exceptions;
using Data.Common;
using Data.Contracts.ApplicationModels;
using Data.Contracts.Models;

namespace Implementation
{
    internal class UsersApplicationModel : BaseApplicationModel, IUsersApplicationModel
    {
        ObservableCollection<IUser> _observableUserCollection = new ObservableCollection<IUser>();
        private IEnumerable<IUser> _userCollection
        {
            get { return _observableUserCollection; }
        }

        public Task<IEnumerable<IUser>> GetAllUsers()
        {
            return Task.Factory.StartNew(() => { return _userCollection; });
        }

        public IUser CreateUser()
        {
            return new BaseUser(Guid.Empty);
        }

        public Task UpdateUser(IUser user)
        {
            return Task.Factory.StartNew(() =>
            {
                BaseUser bu = user as BaseUser;
                Debug.Assert(bu != null);

                if (bu.Id == Guid.Empty)
                {
                    bu.Id = Guid.NewGuid();
                    _observableUserCollection.Add(bu);
                }
                else
                {
                    IUser original = _observableUserCollection.FirstOrDefault(u => u.Id == user.Id);
                    if (original != null)
                    {
                        if (!TryCopyModel(user, out original))
                            throw new OperationFailedException(string.Format("Failed to update user '{0}'", user.Name));
                    }
                }
            });
        }

        public Task DeleteUser(Guid userId)
        {
            return Task.Factory.StartNew(() =>
            {
                IUser original = _observableUserCollection.FirstOrDefault(u => u.Id == userId);
                if (original != null)
                {
                    _observableUserCollection.Remove(original);
                }
            });
        }
    }
}
